import edu.princeton.cs.algs4.*;
import java.util.Comparator;

public class Insertion {

    private Insertion() {}

    /* 思路可以和整理扑克牌顺序时一张一张插入进行类比 */
    /* 为了给要插入的元素腾出位置，需要将其余所有元素向右移动一位 */
    /* "当前索引" 左边的元素都是有序的，但它们最终位置还不确定 */
    /* 为了给更小元素腾出位置，它们有可能会被移动 */
    /* ## 运行时间跟输入元素的初始顺序有关 ## */
    /* ## 即比较次数和交换次数跟输入的初始顺序有关 ## */
    public static void sort(Comparable <?>[] a) {

        int n = a.length;

        for(int i = 1; i < n; i++) {

            /* ## CURRENT INDEX i */

            /* Insert a[i] into the array:a[i-1] a[i-2]...a[0] */
            for(int j = i; j > 0 && less(a[j], a[j-1]); j--) {
                exch(a, j, j-1);
            }

            assert isSorted(a, 0, i);
        }

        assert isSorted(a);

    }
    public static void sort(Comparable <?> [] a, int lo, int hi) {

        for(int i = lo + 1; i < hi; i++) {
            /* Insert a[i] into the array:a[i-1] a[i-2]... */
            for(int j = i; j > lo && less(a[j], a[j-1]); j--) {
                exch(a, j, j-1);
            }
        }

        assert isSorted(a, lo, hi);

    }
    public static void sort(Object[] a, Comparator <?> comparator) {
        int n = a.length;

        for(int i = 1; i < n; i++) {
            for(int j = i; j > 0 && less(a[j], a[j-1], comparator); j--) {
                exch(a, j, j-1);
            }
            assert isSorted(a, 0, i, comparator);
        }

        assert isSorted(a, comparator);
    }

    public static void sort(Object[] a, int lo, int hi, Comparator <?> comparator) {

        for(int i = lo + 1; i < hi; i++) {
            for(int j = i; j > lo && less(a[j], a[j-1], comparator); j--) {
                exch(a, j, j-1);
            }
        }

        assert isSorted(a, lo, hi, comparator);

    }

    public static int[] indexSort(Comparable <?> [] a) {
        int n = a.length;
        int[] index = new int[n];
        for(int i = 0; i < n; i++) {
            index[i] = i;
        }

        for(int i = 1; i < n; i++) {
            for(int j = i; j > 0 && less(a[index[j]], a[index[j-1]]); j--) {
                exch(index, j, j-1);
            } 
        }

        return index;
        
    }

    /*****************************
     * Helper sorting functions.
     *****************************/

    // is v < w ?
    private static boolean less(Comparable v, Comparable w) {
        return v.compareTo(w) < 0;
    }
    //is v < w ? 
    private static boolean less(Object v, Object w, Comparator comparator) {
        return comparator.compare(v, w) < 0;
    }
    //exchange a[i] and a[j]
    private static void exch(Object[] a, int i, int j) {
        Object swap = a[i];
        a[i] = a[j];
        a[j] = swap;
    }
    //exchange a[i] and a[j] (for indirect sort)
    private static void exch(int[] a, int i, int j) {
        int swap = a[i];
        a[i] = a[j];
        a[j] = swap;
    }
    /************************
     * Check if array is sorted - useful for debugging 
     ************************/

    private static boolean isSorted(Comparable <?> [] a) {
        return isSorted(a, 0, a.length);
    }
    // is the array a[lo..hi) sorted
    private static boolean isSorted(Comparable <?> [] a, int lo, int hi) {

        for(int i = lo + 1; i < hi; i++) {
            if(less(a[i], a[i-1])) 
                    return false;
        }

        return true;

    }

    private static boolean isSorted(Object[] a, Comparator comparator) {

        return isSorted(a, 0, a.length, comparator);

    }
    // is the array a[lo..hi) sorted
    private static boolean isSorted(Object[] a, int lo, int hi, Comparator comparator) {

        for(int i = lo + 1; i < hi; i++) {
            if(less(a[i], a[i-1], comparator))
                return false;
        }
        return true;

    }

    // print array to standard output
    private static void show(Comparable[] a) {
        for(int i = 0; i < a.length; i++) {
            StdOut.println(a[i]);
        }

    }

    public static void main(String[] args) {
        String[] a = StdIn.readAllStrings();
        Insertion.sort(a);
        show(a);
    }

}
